<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<!-- InstanceBegin template="/Templates/soramimi.dwt" codeOutsideHTMLIsLocked="true" -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="style/style.css" type="text/css" />
<!-- #BeginEditable "doctitle" -->
<title>コーディングスタイル</title>
<style>
<!--
pre.good {
	border: 1px solid #00c000;
}
pre.bad {
	border: 1px solid #c00000;
}
-->
</style>
<!-- #EndEditable -->
</head>
<body bgcolor="#f0f0f0" background="style/bg.gif">
<div id="body">
<div id="header">
  <div style="float: left"><a href="https://soramimi.github.io/Guitar/"><img src="banner.png" width="443" height="48" alt="Guitar - the graphical git client"></a></div>
  <div style="text-align: right;">under development</div>
  <div style="clear: both;"></div>
</div>
<!-- #BeginEditable "content" -->
<h1>コーディングスタイル</h1>
<h2>命名規則</h2>
<ul>
  <li>ファイル名
    <ul>
      <li>UpperCamelCase.cpp （原則）</li>
      <li>lowercase.cpp （一部例外）</li>
    </ul>
  </li>
  <li>typedef型名
    <ul>
      <li>snake_case_t （そのときの気分で適当に決める） </li>
      <li>UpperCamelCase（クラスや構造体の場合）</li>
    </ul>
  </li>
  <li>クラス／構造体名
    <ul>
      <li> UpperCamelCase</li>
    </ul>
  </li>
  <li>関数名
    <ul>
      <li>lowerCamelCase （原則）</li>
      <li>snake_case （時々）</li>
      <li>UpperCamelCase （Windows用）</li>
    </ul>
  </li>
  <li>メンバ変数名
    <ul>
      <li>snake_case</li>
    </ul>
  </li>
  <li>ローカル変数名
    <ul>
      <li>snake_case</li>
      <li>lowercase  （そのときの気分で適当に決める） </li>
      <li>ローカル変数名には原則として大文字を使わない</li>
    </ul>
  </li>
  <li>ラムダ式名
    <ul>
      <li>auto UpperCamelCase = [](){}; （原則）</li>
      <li>auto lowerCamelCase = [](){}; （時々）</li>
    </ul>
  </li>
  <li>enum型名
    <ul>
      <li>UpperCamelCase</li>
    </ul>
  </li>
  <li>enumメンバ
    <ul>
      <li>UpperCamelCase（原則）</li>
      <li>UPPER_SNAKE_CASE（時々）</li>
    </ul>
  </li>
  <li>プリプロセッサシンボル
    <ul>
      <li>UPPER_SNAKE_CASE （原則）</li>
      <li>UpperCamelCase （時々）</li>
    </ul>
  </li>
</ul>
<h3>接頭辞・接尾辞・ハンガリアン記法</h3>
<p>接頭辞やハンガリアン記法は採用しない。</p>
<h4>クラス名</h4>
<ul>
  <li>先頭に特定の文字を付ける様なクラス名にはしない。</li>
</ul>
<pre class="bad">class CHoge {
};</pre>
<h4>変数名</h4>
<ul>
  <li>m_ や g_ の様なものは付けない。</li>
</ul>
<pre class="bad">
class Hoge {
private:
    int m_value;
};
Hoge g_hoge;</pre>
<ul>
  <li>アンダースコアで終わる。（とりあえず不問。将来のリファクタリング対象）</li>
</ul>
<pre>class Hoge {
private:
	int value_;
};</pre>
<h4>接頭辞</h4>
<ul>
  <li>禁止はしないが積極的には使わない。</li>
  <li>状況次第、あった方がいいと判断すれば使う。</li>
</ul>
<pre>bool fCondition;
char *pSomething;</pre>
<h4>接尾辞</h4>
<ul>
  <li>状況次第、あった方がいいと判断すれば使う。</li>
</ul>
<pre>char *dataptr;
std::shared_ptr&lt;Hoge&gt; hoge_ptr;</pre>
<h4>絶対厳禁</h4>
<ul>
  <li>Windows由来のシステムハンガリアン記法は厳禁</li>
</ul>
<pre class="bad">char *lpszText;</pre>
<h2>インデントと空白と改行</h2>
<ul>
  <li>ハードタブ</li>
  <li>4文字幅を推奨</li>
</ul>
<h3>桁揃え</h3>
<ul>
  <li>行先頭のインデントだけハードタブ、それ以外の桁揃えは空白文字を使う。</li>
</ul>
<pre class="good">	switch (n) {
	case 1:    return &quot;a&quot;;    // comment
	case 12:   return &quot;ab&quot;;   // comment
	case 123:  return &quot;abc&quot;;  // comment
	}</pre>
<h3>if</h3>
<pre class="good">	if (cond1) {
		// do something
	} else if (cond2) {
		// do something
	} else {
		// do something
	}</pre>
<ul>
  <li>開き括弧の前に1個の空白を入れる。</li>
  <li>閉じ括弧と波括弧の間に1個の空白を入れる。波括弧の前で改行はしない。</li>
  <li>elseの前後で改行しない。</li>
  <li>条件式が読みにくいとき、わざと if ブロックで何も行わず else ブロックを利用することがある。</li>
</ul>
<h4>読みにくい</h4>
<pre class="bad">	if (c != 'a' &amp;&amp; c != 'b' &amp;&amp; c != 'c') {
		// do something
	}</pre>
<h4>良い</h4>
<pre class="good">	if (c == 'a' || c == 'b' || c == 'c') {
		// nop
	} else {
		// do something
	}</pre>
<h3>while</h3>
<pre class="good">	while (cond) {
		// do something
	}</pre>
<ul>
  <li>開き括弧の前に1個の空白を入れる。</li>
  <li>閉じ括弧と波括弧の間に1個の空白を入れる。波括弧の前で改行はしない。</li>
</ul>
<h3>do while</h3>
<pre class="good">	do {
		// do something
	} while (cond);</pre>
<ul>
  <li>波括弧の前に1個の空白を入れる。改行はしない。</li>
  <li>閉じ波括弧の後に1個の空白を入れる。</li>
  <li>開き括弧の前に1個の空白を入れる。</li>
  <li>セミコロンの前に空白は入れない。</li>
</ul>
<h3>for</h3>
<pre class="good">	for (int i = 0; i &lt; 10; i++) {
		// do something
	}</pre>
<ul>
  <li>開き括弧の前に1個の空白を入れる。</li>
  <li>セミコロンの前に空白は入れない。後に1個の空白を入れる。</li>
  <li>閉じ括弧と波括弧の間に1個の空白を入れる。波括弧の前で改行はしない。</li>
</ul>
<h3>switch</h3>
<ul>
  <li>
    <p>switchとcaseのインデントは同じ深さとする。</p>
  </li>
</ul>
<h4>良い</h4>
<pre class="good">	switch (n) {<br>	case 1:
		// do something
		break;
	}</pre>
<h4>良くない</h4>
<pre class="bad">	switch (n) {<br>		case 1:
			// do something
			break;
	}</pre>
<h4>通り抜け</h4>
<ul>
  <li>意図的に break しないときは、fallthruなどのコメントを書く。</li>
</ul>
<pre class="good">	switch (n) {<br>	case 1:
		// do something
		break;
	case 2: // fallthru
	case 3:
		// do something
		break;
	}</pre>
<h3>式</h3>
<ul>
  <li>セミコロンの前に空白を入れない。</li>
  <li>開き括弧の後と閉じ括弧の前に空白を入れない。</li>
  <li>二項演算子の前後に1個の空白を入れる。</li>
  <li>単項演算子の後に空白を入れない。</li>
</ul>
<h4>良い</h4>
<pre class="good">hoge();</pre>
<h4>良くない</h4>
<pre class="bad">hoge() ;</pre>
<h4>良い</h4>
<pre class="good">int n = (12 + 34);</pre>
<h4>良くない</h4>
<pre class="bad">int n = ( 12+34 );</pre>
<h4>良い</h4>
<pre class="good">bool g = !f;</pre>
<h4>良くない</h4>
<pre class="bad">bool g = ! f;</pre>
<h3>カンマ</h3>
<ul>
  <li>カンマの前に空白は入れない。後に1個の空白を入れる。</li>
</ul>
<pre class="good">hoge(a, b, c);
</pre>
<h2>式</h2>
<h3>代入</h3>
<ul>
  <li>条件式内で変数への代入は行わない。</li>
</ul>
<h4>良くない</h4>
<pre class="bad">	while ((c = get()) != 0) {
	}</pre>
<h4>例外</h4>
<pre class="good">	if (Hoge *hogeptr = dynamic_cast&lt;Hoge *&gt;(baseptr)) {
	}</pre>
<h3>変数宣言</h3>
<ul>
  <li>ポインタや参照の記号（* や &amp;）は変数名の側に寄せる。</li>
</ul>
<h4>良い</h4>
<pre class="good">char *p;</pre>
<h4>良くない</h4>
<pre class="bad">char* p;</pre>
<h3>長い文</h3>
<ul>
  <li>途中で改行しない。</li>
  <li>論理的に一行のものは物理的にも一行で記述する原則。</li>
  <li>一行の長さに制限は設けないので、長くなっても構わない。</li>
  <li>どうしても改行しないと読みにくい場合は、慎重に検討する。</li>
</ul>
<h4>良い</h4>
<pre class="good">	if (!CreateProcessW(0, &amp;tmp[0], 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, &amp;si, &amp;pi)) {
	}<br>
</pre>
<h4>良くない</h4>
<pre class="bad">	if (!CreateProcessW(0, &amp;tmp[0], 0, 0, TRUE,
						CREATE_NO_WINDOW, 0, 0, &amp;si, &amp;pi)) {
	}</pre>
<h3>条件式</h3>
<ul>
  <li>true、false、nullptrなどの定数シンボルとの比較は行わない。</li>
  <li>定数と比較する場合は、比較する主体の変数を左辺に書き、値を右辺に書く。</li>
</ul>
<h4>良い</h4>
<pre class="good">	bool f;
	if (f) {
	}
	if (!f) {
	}</pre>
<h4>良くない</h4>
<pre class="bad">	bool f;
	if (f == true) {
	}
	if (f == false) {
	}</pre>
<h4>厳禁</h4>
<pre class="bad">	bool f;
	if (true == f) {
	}
	if (false == f) {
	}</pre>
<h4>良い</h4>
<pre class="good">	char *p;
	if (p) {
	}
	if (!p) {
	}</pre>
<h4>良くない</h4>
<pre class="bad">	char *p;
	if (p != nullptr) {
	}
	if (p == nullptr) {
	}</pre>
<h4>厳禁</h4>
<pre class="bad">	char *p;
	if (nullptr != p) {
	}
	if (nullptr == p) {
	}</pre>
<h4>良い</h4>
<pre class="good">	int n;
	if (n == 42) {
	}</pre>
<h4>厳禁</h4>
<pre class="bad">	int n;
	if (42 == n) {
	}</pre>
<h4>良い</h4>
<pre class="good">	if (c &gt;= '0' &amp;&amp; c &lt;= '9') {
	}</pre>
<h4>原則避ける</h4>
<pre class="bad">	if ('0' &lt;= c &amp;&amp; c &lt;= '9') {
	}</pre>
<h2>関数</h2>
<ul>
  <li>宣言は原則として一行で書く。</li>
  <li>関数定義の開き波括弧の前に改行する。</li>
  <li>どうしても引数が長くなりすぎるときは、引数を構造体にまとめて、そのポインタを渡すような方法を検討する。</li>
</ul>
<h4>良い</h4>
<pre class="good">void hoge(int arg1, int arg2, int arg3)
{
}</pre>
<h4>できるだけ避ける</h4>
<pre class="bad">void hoge(int arg1,
		  int arg2,
		  int arg3)
{
}</pre>
<h4>厳禁</h4>
<pre class="bad">void
hoge(int arg1, int arg2, int arg3) {
}
</pre>
<h4>要検討</h4>
<pre class="good">
struct HogeArgs {
	int arg1;
	int arg2;
	int arg3;
};
void hoge(HogeArgs *args)
{
}</pre>
<h3>ポインタ引数</h3>
<ul>
  <li>参照型の引数に代入しない。引数経由で値を返す場合はポインタを使用する。参照を使うときは必ずconstにする。</li>
  <li>引数に構造体を渡す場合、ポインタにするかconst参照にするかは問わない。</li>
</ul>
<h4>良い</h4>
<pre class="good">void func(int *v)
{
	*v = 123;
}</pre>
<h4>厳禁</h4>
<pre class="bad">void func(int &amp;v)
{
	v = 123;
}</pre>
<h4>良い</h4>
<pre class="good">void func(Hoge *hoge)
{
}</pre>
<h4>厳禁</h4>
<pre class="bad">void func(Hoge &amp;hoge)
{
}</pre>
<h4>良い</h4>
<pre class="good">void func(Hoge const *hoge)
{
}</pre>
<h4>良い</h4>
<pre class="good">void func(Hoge const &amp;hoge)
{
}
</pre>
<h2>const</h2>
<ul>
  <li>とにかく積極的にconstを使う。</li>
  <li>ポインタはconstが原則。</li>
  <li>どうしてもconstにできないものだけconstを外す。</li>
  <li>参照型は全てconstにする。  非const参照を使うくらいならポインタにする。</li>
  <li>クラスメンバ関数はできるだけconst関数。</li>
</ul>
<blockquote>
  <pre>class Hoge {
	int getValue() const
	{
		return value;
	}
};</pre>
</blockquote>
<ul>
  <li>range-based-for 等で非const参照を受け取る場合はやむを得ない。
    <pre>std::vector&lt;Hoge&gt; hogevec;
for (Hoge &amp;hoge : hogevec) {
	// do something
}</pre>
  </li>
  <li>constの位置、 <span class="code"> char const *</span> と書くか、 <span class="code">const char *</span> と書くかは不問。</li>
</ul>
<h2>名前空間</h2>
<ul>
  <li>ヘッダファイルに using namespace を書かない。</li>
  <li>すべてのヘッダファイルをインクルードし終わった後  using namespace を書いて良い。</li>
  <li>using namespace std; は禁止。</li>
  <li>namespaceの波括弧内はインデントしない。</li>
  <li>namespaceの終了波括弧の後に、コメントで名前空間名を書く。</li>
</ul>
<pre>namespace ns1 {
namespace ns2 {

class Hoge {
};

}} // namespace ns1::ns2</pre>
<h2>pimplイディオム</h2>
<p>クラスが大きくなってきたら、pimplイディオムの採用を検討する。ポインタは m を推奨。</p>
<h4>Hoge.h</h4>
<pre>class Hoge {
private:
	struct Private;
	Private *m;
public:
	Hoge();
	~Hoge();
];</pre>
<h4>Hoge.cpp</h4>
<pre>struct Hoge::Private {
};

Hoge::Hoge()
	: m(new Private)
{
}

Hoge::~Hoge()
{
	delete m;
}</pre>
<p>クラスメンバ関数内で、pimplイディオム以外の用途で m という変数を使用することを避ける。</p>
<h2>ライブラリ</h2>
<ul>
  <li>cin、cout、cerr、および、&lt;iostream&gt;系のクラスは使用禁止。</li>
</ul>
<!-- #EndEditable -->
<div id="footer"> <span id="copyright"></span> </div>
</body>
<script type="text/javascript" src="common.js"></script>
<!-- InstanceEnd -->
</html>
